package role

import (
	"context"
	"errors"
	"fmt"
	"golang.org/x/sync/errgroup"
	"net/http"
	"wms/model"

	"wms/internal/svc"
	"wms/internal/types"

	"github.com/zeromicro/go-zero/core/logx"
)

type MenuDistributeLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

func NewMenuDistributeLogic(ctx context.Context, svcCtx *svc.ServiceContext) *MenuDistributeLogic {
	return &MenuDistributeLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *MenuDistributeLogic) MenuDistribute(req *types.RoleMenusRequest) (resp *types.BaseResponse, err error) {
	resp = new(types.BaseResponse)

	//角色权限写入casbin
	//1.查询分配的菜单是否存在
	var g errgroup.Group
	for _, menuId := range req.MenusId {
		id := menuId
		g.Go(func() error {
			//var one *model.Menu
			_, e := l.svcCtx.MenuModel.FindOne(l.ctx, id)
			switch e {
			case nil:
			case model.ErrNotFound:
				fmt.Printf("[Error]菜单[%d]不存在\n", id)
				return errors.New("部分菜单不存在")
			default:
				fmt.Printf("[Error]查询菜单[%d]:%s\n", id, e.Error())
				return errors.New("服务内部错误")
			}
			return nil
		})
	}

	if err = g.Wait(); err != nil {
		resp.Code = http.StatusBadRequest
		resp.Msg = err.Error()
		return resp, nil
	}

	//2. 删除角色对应的菜单
	roleMenus, err := l.svcCtx.RoleMenuModel.FindByPage(l.ctx, fmt.Sprintf(" where role_id=%d", req.RoleId))
	if err != nil {
		fmt.Printf("[Error]查询角色[%d]菜单:%s\n", req.RoleId, err.Error())
		resp.Code = http.StatusInternalServerError
		resp.Msg = "服务内部错误"
		return resp, nil
	}

	for _, m := range roleMenus {
		one := m
		g.Go(func() error {
			e := l.svcCtx.RoleMenuModel.Delete(l.ctx, one.Id)
			if e != nil {
				fmt.Printf("[Error]删除角色菜单[%d]:%s\n", one.Id, e.Error())
			}
			return e
		})
	}

	if err = g.Wait(); err != nil {
		resp.Code = http.StatusInternalServerError
		resp.Msg = "服务内部错误"
		return resp, nil
	}

	//3.角色添加菜单
	for _, menuId := range req.MenusId {
		one := menuId
		//3.1 角色添加菜单[role_menu]
		g.Go(func() error {
			_, e := l.svcCtx.RoleMenuModel.Insert(l.ctx, &model.RoleMenu{
				RoleId: req.RoleId,
				MenuId: one,
			})
			if e != nil {
				fmt.Printf("[Error]角色[%d]添加菜单[%d]:%s\n", req.RoleId, one, e.Error())
			}
			return e
		})
	}

	if err = g.Wait(); err != nil {
		resp.Code = http.StatusInternalServerError
		resp.Msg = "服务内部错误"
		return resp, nil
	}

	resp.Code = http.StatusOK
	resp.Msg = "成功"
	return resp, nil
}
